package reese.think_in_java.java_21_thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * ***********************************************************
 *
 * @类名 : reese.think_in_java.java_21_thread.类名
 * @DESCRIPTION : 这家伙太懒啥都没写
 * @AUTHOR :  一个风情万种的男子
 * @DATE : 2016/6/1
 * ***********************************************************
 */

// Reuses storage so we don't run out of memory
class CircularSet{
    private int[] array ;
    private int len;
    private int index = 0;
    public CircularSet(int size){
        array = new int[size];
        len = size ;

        // Initialize to a value not produced
        // by the serialNumberGenerator
        for(int i=0;i<size;i++){
            array[i] = -1 ;
        }
    }

    public synchronized void  add(int i){
        array[index] = i ;
        //wrap  index and write over old elements
        index = ++index % len ;
    }
    public synchronized  boolean contains(int val){
        for (int i=0;i<len;i++){
            if (array[i]==val) {
                return  true ;
            }
        }
        return false ;
    }
}


//持有所有的序列数
public class SerialNumberChecker {

    private  static  final  int SIZE = 10 ;
    private  static  CircularSet serials = new CircularSet(1000);

    private  static ExecutorService exec = Executors.newCachedThreadPool();

    //确保所有序列数是唯一的
    static  class  SerialChecker implements  Runnable {

        public void run() {
            while (true){
                int serial =  SerialNumberGenerator.nextSerialNumber();
                if(serials.contains(serial)){
                    System.out.println("Duplicate: "+ serial);
                    System.exit(0);
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i=0;i<SIZE;i++){
            exec.execute(new SerialChecker());
        }
        // stop after n seconds if there's an argument:
        if(args.length >0){
            TimeUnit.SECONDS.sleep(new Integer(args[0]));
            System.out.println("No duplicates detected");
            System.exit(0);
        }
    }
}
